package org.aceor.tennis.web.controller;

import com.google.common.base.Optional;
import lombok.extern.slf4j.Slf4j;
import org.aceor.tennis.common.domain.Play;
import org.aceor.tennis.common.domain.User;
import org.aceor.tennis.common.domain.UserPlayRel;
import org.aceor.tennis.common.enums.ErrorCode;
import org.aceor.tennis.common.exception.BusinessRuntimeException;
import org.aceor.tennis.service.IPlayService;
import org.aceor.tennis.service.IUserPlayRelService;
import org.aceor.tennis.service.IUserService;
import org.aceor.tennis.web.dto.BaseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.stream.Collectors;

import static org.aceor.tennis.web.dto.BaseResult.buildError;
import static org.aceor.tennis.web.dto.BaseResult.buildSuccess;
import static org.aceor.tennis.web.util.WebUtil.attainErrorInfoFromBindingResult;

/**
 * /signUp
 * Get: 查看结果
 * Post: 执行报名
 * Put: 同意 不同意
 * Created by lxue on 16/5/14.
 */
@RestController
@Slf4j
public class PlayController {
    @Autowired
    private IPlayService<Play> playService;

    @Autowired
    private IUserPlayRelService<UserPlayRel> userPlayRelService;

    @Autowired
    private IUserService<User> userService;

    /**
     * 查看报名结果(是否报名成功)
     *
     * @param userId
     * @param playId
     * @return
     */
    @RequestMapping(value = "play/signUp", method = {RequestMethod.GET})
    public BaseResult<Boolean> playSignUpResult(
            @RequestParam("userId") Long userId,
            @RequestParam("playId") Long playId) {
        Optional<UserPlayRel> userPlayRelOptional = userPlayRelService.queryOneUserPlayRel(userId, playId);
        if (userPlayRelOptional.isPresent()) {
            return buildSuccess(Boolean.TRUE);
        } else {
            return buildSuccess(Boolean.FALSE);
        }
    }

    /**
     * 报名
     *
     * @param userId
     * @param playId
     * @return
     */
    @RequestMapping(value = "play/signUp", method = {RequestMethod.POST})
    public BaseResult<Long> signUpOnePlay(
            @RequestParam("userId") Long userId,
            @RequestParam("playId") Long playId) {
        Optional<UserPlayRel> userPlayRelOptional = userPlayRelService.signUpOnePlay(userId, playId);
        if (userPlayRelOptional.isPresent()) {
            return buildSuccess(userPlayRelOptional.get().getId());
        }
        return buildError(ErrorCode.SIGNUP_ERROR);
    }

    /**
     * 同意报名
     *
     * @param userId
     * @param playId
     * @return
     */
    @RequestMapping(value = "play/signUp/agree", method = {RequestMethod.PUT})
    public BaseResult agreeSignUpOnePlay(
            @RequestParam("userId") Long userId,
            @RequestParam("playId") Long playId) {
        userPlayRelService.agreeSignUpOnePlay(userId, playId);
        return buildSuccess(null);
    }

    /**
     * 不同意报名
     *
     * @param userId
     * @param playId
     * @return
     */
    @RequestMapping(value = "play/signUp/disagree", method = {RequestMethod.PUT})
    public BaseResult disagreeSignUpOnePlay(
            @RequestParam("userId") Long userId,
            @RequestParam("playId") Long playId) {
        userPlayRelService.disAgreeSignUpOnPlay(userId, playId);
        return buildSuccess(null);
    }

    /**
     * 查看某个球局
     *
     * @param playId
     * @return
     */
    @RequestMapping(value = "play/{playId}", method = {RequestMethod.GET})
    public BaseResult<Play> queryPlayById(@PathVariable("playId") Long playId) {
        return buildSuccess(playService.fetch(playId));
    }

    /**
     * 创建球局
     *
     * @param play
     * @param bindingResult
     * @return
     */
    @RequestMapping(value = "play", method = {RequestMethod.POST})
    public BaseResult<Play> createOnePlay(
            @Valid @RequestBody Play play,
            BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            String error = attainErrorInfoFromBindingResult(bindingResult);
            throw new BusinessRuntimeException(ErrorCode.PARAM_ERROR, error);
        }
        if (1 == playService.add(play)) {
            buildSuccess(play);
        }
        return buildError("创建球局失败");
    }

    /**
     * 所有球局
     *
     * @param rows
     * @param offset
     * @return
     */
    @RequestMapping(value = "plays", method = {RequestMethod.GET})
    public BaseResult<List<Play>> findAllPlays(
            @RequestParam(value = "offset", defaultValue = "0") Integer offset,
            @RequestParam(value = "rows", defaultValue = "10") Integer rows) {
        List<Play> playList = playService.queryUnderwayPlays(offset, rows);
        return buildSuccess(playList);
    }

    /**
     * 用户自己的球局
     *
     * @param userId
     * @return
     */
    @RequestMapping(value = "plays/{userId}", method = {RequestMethod.GET})
    public BaseResult<List<Play>> findSelfPlays(@PathVariable("userId") Long userId) {
        //自己创建的
        List<Play> playList = playService.queryAllSelfCreatePlays(userId);
        //加入成功的
        List<Play> hasJoinPlayList = userPlayRelService
                .queryHasJoinPlays(userId)
                .stream()
                .map(userPlayRel -> playService.fetch(userPlayRel.getUserId()))
                .collect(Collectors.toList());
        hasJoinPlayList.addAll(playList);
        return buildSuccess(hasJoinPlayList);
    }

    @RequestMapping(value = "play/{playId}/users")
    public BaseResult<List<User>> findHasSignUpUsers(
            @PathVariable("playId") Long playId) {
        List<User> userList = userPlayRelService
                .queryHasSignUpUsers(playId)
                .stream()
                .map(userPlayRel -> userService.fetch(userPlayRel.getUserId()))
                .collect(Collectors.toList());
        return buildSuccess(userList);
    }
}
